﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Configuration;
using System.Reflection;

namespace WebApplicationBack
{
    public class ApplicationBackup
    {
        public static readonly string Mail_Postfix = "\r\n\r\n\r\n{0}\r\n（本邮件由系统自动发出，请勿回复。）";

        string _webSiteFolder = string.Empty;
        string _resourceFolder = string.Empty;
        string _dbFolder = string.Empty;
        string _webSiteZip = "website.zip";
        string _resourceZip = "resources.zip";
        string _dbZip = "db.zip";
        string _tmpFolder = "backup";
        string _ftpServer = "114.80.100.249:2121";
        string _ftpUser = "ldsp";
        string _ftpPassword = "ldsp";
        string _mailList = "";
        string _logFile = "";
        string _fileBackupLog = "";
        string _zipPassword = "VerySecret789&*(";

        string _currentDir = Assembly.GetExecutingAssembly().Location.Substring(0, Assembly.GetExecutingAssembly().Location.LastIndexOf("\\"));
        FileOperation _op = new FileOperation();
        IList<string> _pdfBackup = new List<string>();//本次备份的PDF

        public ApplicationBackup()
        {
            InitializeConfig();
        }

        private void InitializeConfig()
        {
            _webSiteFolder = ConfigurationManager.AppSettings["WebSiteFolder"];
            _resourceFolder = ConfigurationManager.AppSettings["ResourceFolder"];
            _dbFolder = ConfigurationManager.AppSettings["DBFolder"];
            _webSiteZip = ConfigurationManager.AppSettings["WebSiteZipName"];
            _resourceZip = ConfigurationManager.AppSettings["ResourceZipName"];
            _dbZip = ConfigurationManager.AppSettings["DBZipName"];
            _tmpFolder = Path.Combine(_currentDir, ConfigurationManager.AppSettings["TempFolder"]);
            _ftpServer = ConfigurationManager.AppSettings["FTPServer"];
            _ftpUser = ConfigurationManager.AppSettings["FTPUser"];
            _ftpPassword = ConfigurationManager.AppSettings["FTPPassword"];
            _mailList = ConfigurationManager.AppSettings["MailList"];
            _zipPassword = ConfigurationManager.AppSettings["ZipPassword"];

            _logFile = Path.Combine(_currentDir, "log.txt");

            //查找已备份的PDF.
            _fileBackupLog = Path.Combine(_currentDir, "backupFiles.txt");
            if (!File.Exists(_fileBackupLog))
            {
                File.Create(_fileBackupLog);
            }
        }

        public void Run()
        {
            _op.AppendFileByLine(_logFile, DateTime.Now.ToString() + " : 开始");
            _op.AppendFileByLine(_logFile, "=================================================================");

            try
            {
                EmptyTempFolder();
                ZipWebSite();
                ZipResources();
                ZipDBFiles();
                BackUpToServer();
                LogBackupResources();
            }
            catch (Exception ex)
            {
                _op.AppendFileByLine(_logFile, "ERROR - MESSAGE: " + ex.Message + "Inner Exception[" + ex.InnerException + "]");
                _op.AppendFileByLine(_logFile, "      - STACK TRACE: " + ex.StackTrace);

                MailSender.SendMail(new List<string>() { _mailList }, "每日备份失败", "备份失败" + string.Format(Mail_Postfix, DateTime.Now.ToShortDateString()), new List<string>() { _logFile }, new List<string>() { _logFile });

                return;
            }

            _op.AppendFileByLine(_logFile, "=================================================================");
            _op.AppendFileByLine(_logFile, DateTime.Now.ToString() + " : 结束");

            MailSender.SendMail(new List<string>() { _mailList }, "每日备份成功", "备份成功" + string.Format(Mail_Postfix, DateTime.Now.ToShortDateString()), new List<string>() { }, new List<string>() { });
        }

        private void LogBackupResources()
        {
            foreach (string pdf in _pdfBackup)
            {
                _op.AppendFileByLine(_fileBackupLog, pdf.Substring(pdf.LastIndexOf("\\") + 1));
            }
        }

        private void EmptyTempFolder()
        {
            //开始清空临时目录
            _op.AppendFileByLine(_logFile, DateTime.Now.ToString() + " : 开始清空临时目录。。。");

            DirectoryInfo dir = new DirectoryInfo(_tmpFolder);

            DirectoryInfo[] dirs = dir.GetDirectories();
            foreach (DirectoryInfo d in dirs)
            {
                d.Delete(true);
            }

            FileInfo[] files = dir.GetFiles();
            foreach (FileInfo f in files)
            {
                f.Delete();
            }

            //结束清空临时目录
            _op.AppendFileByLine(_logFile, DateTime.Now.ToString() + " : 结束清空临时目录。。。");
        }

        private void BackUpToServer()
        {
            //开始往服务器备份
            _op.AppendFileByLine(_logFile, DateTime.Now.ToString() + " : 开始往服务器备份。。。");

            string ftpDir = "BACKUP/" + DateTime.Now.ToString("yyyyMMdd");

            FTPOperation ftpOp = new FTPOperation(_ftpServer, _ftpUser, _ftpPassword);

            ftpOp.MakeDir(ftpDir);

            _op.AppendFileByLine(_logFile, DateTime.Now.ToString() + " : 开始备份网站。。。");
            ftpOp.Upload(_tmpFolder + "\\" + _webSiteZip, ftpDir);
            _op.AppendFileByLine(_logFile, DateTime.Now.ToString() + " : 开始备份资源。。。");
            ftpOp.Upload(_tmpFolder + "\\" + _resourceZip, ftpDir);
            _op.AppendFileByLine(_logFile, DateTime.Now.ToString() + " : 开始备份数据库。。。");
            ftpOp.Upload(_tmpFolder + "\\" + _dbZip, ftpDir);

            //结束往服务器备份
            _op.AppendFileByLine(_logFile, DateTime.Now.ToString() + " : 结束往服务器备份。。。");
        }

        private void ZipDBFiles()
        {
            //开始压缩数据库备份文件
            _op.AppendFileByLine(_logFile, DateTime.Now.ToString() + " : 开始打包数据库备份文件。。。");

            string tmpDB = _tmpFolder + "\\DB";
            _op.CopyFiles(_dbFolder, tmpDB, null);
            _op.ZipFileDictory(tmpDB, _tmpFolder + "\\" + _dbZip, _zipPassword);

            //结束压缩数据库备份文件
            _op.AppendFileByLine(_logFile, DateTime.Now.ToString() + " : 结束打包数据库备份文件。。。");
        }

        private void ZipResources()
        {
            //开始压缩资源，比如PDF
            _op.AppendFileByLine(_logFile, DateTime.Now.ToString() + " : 开始打包资源，比如PDF。。。");

            //获取当前PDF列表.
            IList<string> resources = new List<string>();
            string[] pdfs = Directory.GetFiles(_resourceFolder);

            if (pdfs.Length > 0)
            {
                foreach (string s in pdfs)
                {
                    resources.Add(s.Substring(s.LastIndexOf("\\") + 1));
                }
            }

            //获取未备份的pdf列表.
            IList<string> pdfToBackup = new List<string>();
            IList<string> pdfAlreadyBackup = _op.ReadFileByLine(_fileBackupLog);
            foreach (string pdf in pdfs)
            {
                if (!pdfAlreadyBackup.Contains(pdf.Substring(pdf.LastIndexOf("\\") + 1)))
                {
                    pdfToBackup.Add(pdf);
                }
            }

            //拷贝未备份的pdf，记录已拷贝的文件到日志文件
            string resourceDir = _tmpFolder + "\\Resources\\";
            if (!Directory.Exists(resourceDir))
            {
                Directory.CreateDirectory(resourceDir);
            }

            foreach (string pdf in pdfToBackup)
            {
                File.Copy(pdf, resourceDir + pdf.Substring(pdf.LastIndexOf("\\")), true);
                _pdfBackup.Add(pdf);
            }

            _op.ZipFileDictory(resourceDir, _tmpFolder + "\\" + _resourceZip, _zipPassword);

            //结束压缩资源，比如PDF
            _op.AppendFileByLine(_logFile, DateTime.Now.ToString() + " : 结束打包资源，比如PDF。。。");
        }

        private void ZipWebSite()
        {
            //开始打包网站
            _op.AppendFileByLine(_logFile, DateTime.Now.ToString() + " : 开始打包网站。。。");

            string tmpwebSite = _tmpFolder + "\\WebSite";
            _op.CopyFiles(_webSiteFolder, tmpwebSite, new List<string>() { _webSiteFolder + "\\Docs" });
            _op.ZipFileDictory(tmpwebSite, _tmpFolder + "\\" + _webSiteZip, _zipPassword);

            //结束打包网站
            _op.AppendFileByLine(_logFile, DateTime.Now.ToString() + " : 结束打包网站。。。");
        }
    }
}
